package com.zhiwang.planet.mvvm.binding

import android.graphics.drawable.Drawable
import android.text.TextUtils
import android.text.method.LinkMovementMethod
import android.text.method.MovementMethod
import android.view.LayoutInflater
import android.view.View
import android.view.View.OnClickListener
import android.view.ViewGroup
import android.widget.*
import androidx.core.content.ContextCompat
import androidx.databinding.BindingAdapter
import androidx.databinding.BindingConversion
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.Adapter
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.Target
import com.bumptech.glide.request.target.Target.SIZE_ORIGINAL
import com.scwang.smartrefresh.layout.SmartRefreshLayout
import com.scwang.smartrefresh.layout.listener.OnLoadMoreListener
import com.scwang.smartrefresh.layout.listener.OnRefreshListener
import com.zhiwang.planet.R
import com.zhiwang.planet.mvvm.model.entity.main.Diamond
import com.zhiwang.planet.mvvm.model.entity.main.HomeRecommend
import com.zhiwang.planet.ui.glide.transformation.XhpiBitmapTransformation
import com.zhiwang.planet.widget.ExpandableTextView
import com.zhiwang.planet.widget.MsgRadioButton
import com.zhiwang.planet.widget.ShuffleLayout
import com.zhiwang.planet.widget.ShuffleLayout.OnDiamondClickListener
import com.zhiwang.planet.widget.ShuffleLayout.OnDiamondEmptyListener
import java.io.File
import java.lang.IllegalStateException
import kotlin.math.roundToInt


val TAG = "ViewBinding"

/**
 * class for attribute binding in xml or create two-way binding for custom views
 */
@BindingAdapter("imageUrl", "imageRes", "bindScaleImageUrl", "imageFile", "filePlaceHolderRes", requireAll = false)
fun bindImage(view: ImageView, imageUrl: String?, res: Int, scaleImageUrl: String?, file: File?, filePlaceHolderRes: Int?) = with(view) {

    if (file != null) Glide.with(view.context).load(file).into(view)

    if (filePlaceHolderRes != null && filePlaceHolderRes != 0) Glide.with(this.context)
            .load(filePlaceHolderRes)
            .into(this)

    if (TextUtils.isEmpty(imageUrl).not())
        Glide.with(this.context)
                .load(imageUrl)
                .into(this)

    if (res != 0) this.setImageResource(res)

    if (TextUtils.isEmpty(scaleImageUrl).not()) {
        val options = RequestOptions()
                .override(SIZE_ORIGINAL, SIZE_ORIGINAL)//获取原始尺寸
                .transform(XhpiBitmapTransformation)
        Glide.with(this.context)
                .load(scaleImageUrl)
                .apply(options)
                .into(this)
    }


//    autoLoadFunc?.invoke(view)
}


@BindingAdapter("onRefresh")
fun bindSwipeRefreshLayout(swipeRefreshLayout: SwipeRefreshLayout, listener: SwipeRefreshLayout.OnRefreshListener) {

    swipeRefreshLayout.setOnRefreshListener {
        listener.onRefresh()
        swipeRefreshLayout.isRefreshing = false
    }
}

//针对SmartRefreshLayout
@BindingAdapter("onRefresh", "onLoadMore", "refreshing", "loading_more", requireAll = false)
fun bindSmartRefreshLayout(smartRefreshLayout: SmartRefreshLayout,
                           onRefreshListener: OnRefreshListener?, onLoadMoreListener: OnLoadMoreListener?, refreshing: Boolean, loadingMore: Boolean) {
    if (onRefreshListener != null)
        smartRefreshLayout.setOnRefreshListener(onRefreshListener)

    if (onLoadMoreListener != null)
        smartRefreshLayout.setOnLoadMoreListener(onLoadMoreListener)

    if (refreshing.not())
        smartRefreshLayout.finishRefresh()


    if (loadingMore.not())
        smartRefreshLayout.finishLoadMore()
}


@BindingAdapter("items")
fun bindShuffleLayoutData(shuffleLayout: ShuffleLayout, data: List<Diamond>?) {
    if (data != null) {
        if (data.isEmpty()) {
            shuffleLayout.setHintWhenEmpty()
        } else
            shuffleLayout.setData(data)
    } else {
        shuffleLayout.setHintDiamond("登录后收取")
    }
}

@BindingAdapter("recGame")
fun bindShuffleLayoutRecGame(shuffleLayout: ShuffleLayout, name: String) {
    shuffleLayout.setHintWhenEmpty()
}

//shuffleLayout
@BindingAdapter("onDiamondClick", "onEmpty", "bindExtraView", "bindExtraClick", "bindExtraViewData", requireAll = false)
fun bindShuffleLayout(shuffleLayout: ShuffleLayout, listener: OnDiamondClickListener?
                      , emptyListener: OnDiamondEmptyListener?, extraViewLayoutId: Int, extraClickListener: OnClickListener,
                      extraViewData: HomeRecommend?) {
    emptyListener?.apply { shuffleLayout.emptyListener = this }
    if (listener != null)
        shuffleLayout.listener = listener


    val view = LayoutInflater.from(shuffleLayout.context).inflate(extraViewLayoutId, shuffleLayout, false)
    shuffleLayout.setExtra(view)

    shuffleLayout.extraClickListener = extraClickListener

    //extraView data
    shuffleLayout.extraView?.apply {

        val gameDiamond = findViewById<View>(R.id.game_diamond)
        extraViewData?.apply {
            if (iconUrl != null && TextUtils.isEmpty(this.title).not())
                Glide.with(shuffleLayout.context)
                        .load(extraViewData.iconUrl)
                        .listener(object : RequestListener<Drawable> {
                            override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
                                return false;
                            }

                            override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {

                                gameDiamond.scaleY = 1f
                                gameDiamond.scaleX = 1f
                                val animator = gameDiamond.animate()
                                        .alpha(1f)
                                animator.duration = 250
                                animator.start()
                                return false
                            }

                        })
                        .into(findViewById(R.id.image))

            findViewById<TextView>(R.id.title).text = extraViewData.title ?: ""
        }


    }

}


@BindingAdapter("expand")
fun bindExpanableTextView(v: ExpandableTextView, expand: Boolean) {

    if (expand)
        v.expand()
    else v.collapse()

}


@BindingAdapter("show_hint")
fun bindMsgRadioButton(v: MsgRadioButton, hint: Boolean) {
    if (hint)
        v.showHint()
    else v.hideHint()
}

@BindingConversion
fun floatToString(f: Float): String {
    return f.toString()
}


@BindingAdapter("drawableBottomRes")
fun setDrawableBottom(view: TextView, drawableRes: Int) {
    val drawable = if (drawableRes != 0) ContextCompat.getDrawable(view.context, drawableRes) else null
    setIntrinsicBounds(drawable)
    val drawables = view.compoundDrawables
    view.setCompoundDrawables(drawables[0], drawables[1], drawables[2], drawable)
}

private fun setIntrinsicBounds(drawable: Drawable?) {
    drawable?.setBounds(0, 0, drawable.intrinsicWidth, drawable.intrinsicHeight)
}

@BindingAdapter("adapter")
fun setAdapterForRv(rv: RecyclerView, adapter: Adapter<*>) {
    rv.adapter = adapter
}

@BindingAdapter("android:layout_marginTop")
fun setTopMargin(view: View, bottomMargin: Float) {
    val layoutParams = view.getLayoutParams() as ViewGroup.MarginLayoutParams
    layoutParams.setMargins(layoutParams.leftMargin, bottomMargin.roundToInt(),
            layoutParams.rightMargin, layoutParams.bottomMargin)
    view.layoutParams = layoutParams
}


@BindingAdapter("checkedIndex")
fun setCheckedIndexButton(rg: RadioGroup, index: Int) {
    if (rg.childCount > index) {
        rg.check(rg.getChildAt(index).id)
    }
}

@BindingAdapter("backgroundRes")
fun setBackgroundRes(v: View, res: Int) {
    v.setBackgroundResource(res)
}

@BindingAdapter("movement_method")
fun setLinkMovementMethod(compoundButton: TextView, method: String) {
    var movementMethod: MovementMethod? = null
    when (method) {
        "link" -> movementMethod = LinkMovementMethod.getInstance()
        else -> throw  IllegalStateException("unsupported movementMethod")
    }
    compoundButton.movementMethod = movementMethod
}